home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "specs.hpp"
- #include "timage.hpp"
- #include "jwindow.hpp"
- #include "fonts.hpp"
- #include "timing.hpp"
- #include "scene.hpp"
- #include "game.hpp"
- #include "parse.hpp"
- #include "cache.hpp"
- #include <fcntl.h>
-
-
- class string_node
- {
- string_node *l,*r;
- char *n;
- public :
- string_node(char *Name, string_node *Left=NULL, string_node *Right=NULL)
- { l=Left;
- r=Right;
- n=strcpy((char *)jmalloc(strlen(Name)+1,"string node"),Name);
- }
- ~string_node() { jfree(n); }
- char *name() { return n; }
- string_node *left() { return l; }
- string_node *right() { return r; }
- } ;
-
-
- /*class string_tree
- {
- string_node *root;
- public :
- string_tree() { root=NULL; }
- void insert(char *name);
-
- } ; */
-
-
-
- char scene_filename[100];
-
- class scene_frame
- {
- public :
- int picture;
- long time,xc,yc;
-
- scene_frame *next;
- scene_frame(char *&s);
- ~scene_frame() { cash.unreg(picture); }
- } ;
-
-
- scene_frame::scene_frame(char *&s)
- {
- char tmp_name[50];
- expect(get_token(s,tmp_name),sWORD,s);
-
- picture=cash.reg(scene_filename,tmp_name);
- if (picture<0)
- {
- printf("Frame image not found (%s)\n",tmp_name);
- exit(0);
- }
-
-
- xc=yc=0;
- time=-1;
- if (token_type(s)==sLEFT_PAREN) // is a descriptor included?
- {
- next_token(s);
-
- xc=get_number(s);
- if (token_type(s)!=sRIGHT_PAREN)
- {
- yc=get_number(s);
- if (token_type(s)!=sRIGHT_PAREN)
- time=get_number(s);
- }
- expect(get_token(s,tmp_name),sRIGHT_PAREN,s);
- }
-
- next=NULL;
- }
-
-
-
- class scene_sequence : public linked_node
- {
- public :
- char *n;
- scene_frame *first;
- scene_sequence *next;
- scene_sequence(char *&s);
- ~scene_sequence();
- } ;
-
-
-
- scene_sequence::~scene_sequence()
- { jfree(n);
- while (first)
- { scene_frame *p=first;
- first=first->next;
- delete p;
- }
- }
-
-
- scene_sequence::scene_sequence(char *&s)
- {
- scene_frame *cur;
- char tmp_name[50];
- expect(token_type(s),sLEFT_PAREN,s);
- next_token(s);
-
- expect(get_token(s,tmp_name),sWORD,s);
- n=strcpy((char *)jmalloc(strlen(tmp_name)+1,"sequence name"),tmp_name);
- cur=first=new scene_frame(s);
-
- while (token_type(s)!=sRIGHT_PAREN)
- {
- cur->next=new scene_frame(s);
- cur=cur->next;
-
- next=NULL;
- }
- next_token(s);
- next=NULL;
- }
-
-
- class scene_sequence_list
- {
- public :
- scene_sequence *first;
- scene_sequence_list(char *&s);
- scene_sequence *get_seq(char *seq_name);
- ~scene_sequence_list();
- } ;
-
- scene_sequence_list::~scene_sequence_list()
- {
- scene_sequence *p;
- while (first)
- {
- p=first;
- first=first->next;
- delete p;
- }
- }
-
- scene_sequence_list::scene_sequence_list(char *&s)
- {
- scene_sequence *cur;
- expect(token_type(s),sLEFT_PAREN,s);
- next_token(s);
-
- cur=first=new scene_sequence(s);
- while (token_type(s)!=sRIGHT_PAREN)
- {
- cur->next=new scene_sequence(s);
- cur=cur->next;
- }
- next_token(s);
- }
-
- scene_sequence *scene_sequence_list::get_seq(char *seq_name)
- {
- scene_sequence *s=first;
- while (s && strcmp(s->n,seq_name)) s=s->next;
- if (!s)
- {
- printf("No sequence named %s\n",seq_name);
- exit(1);
- }
- return s;
- }
-
-
- class scene_character
- {
- scene_sequence_list *seq_list;
-
- game_object *me;
-
- public :
- char *n;
- scene_character *next;
- scene_sequence *current_seq;
- scene_frame *current_frame;
-
- time_marker *last_frame;
- void draw();
- void area(int &x1, int &y1, int &x2, int &y2);
- scene_character(char *&s);
- void set_seq(char *seq_name)
- { current_seq=seq_list->get_seq(seq_name); }
- int x() { return the_game->screenx(me->x)-cash.fig(current_frame->picture)->xcfg; }
- int y() { return the_game->screeny(me->y)-cash.fig(current_frame->picture)->forward->height(); }
- int next_frame(); // true if sequence is done
- ~scene_character() { jfree(n); delete seq_list; if (last_frame) delete last_frame; }
- } ;
-
-
- int scene_character::next_frame()
- {
- me->x+=current_frame->xc;
- me->y+=current_frame->yc;
-
- current_frame=current_frame->next; // advance the picture
-
- if (last_frame) // save the time stamp, delete old one
- delete last_frame;
- last_frame=new time_marker;
-
- if (!current_frame) // end of sequence?
- {
- current_frame=current_seq->first; // reset and return 1
- return 1;
- }
- else return 0;
- }
-
-
- void scene_character::area(int &x1, int &y1, int &x2, int &y2)
- {
-
- x1=x();
- y1=y();
- y2=x2=0;
-
- scene_frame *p=current_seq->first;
- while (p)
- {
- if (x()+cash.fig(p->picture)->width()-1>x2)
- x2=x()+cash.fig(p->picture)->width()-1;
- if (y()+cash.fig(p->picture)->height()-1>y2)
- y2=y()+cash.fig(p->picture)->height()-1;
- p=p->next;
- }
- }
-
-
- void scene_character::draw()
- {
- cash.fig(current_frame->picture)->forward->put_image(screen,x(),y());
-
- }
-
-
- scene_character::scene_character(char *&s)
- {
- char tmp[100];
- expect(get_token(s,tmp),sLEFT_PAREN,s);
- expect(get_token(s,tmp),sWORD,s);
- n=strcpy((char *)jmalloc(strlen(tmp)+1,"scene character name"),tmp);
- expect(get_token(s,tmp),sNUMBER,s);
-
- /* if (atoi(tmp)==0) */
-
- me=current_level->main_character();
-
-
- seq_list=new scene_sequence_list(s);
- current_seq=seq_list->first;
- current_frame=current_seq->first;
- expect(get_token(s,tmp),sRIGHT_PAREN,s);
-
- last_frame=NULL;
- next=NULL;
- }
-
-
- class scene_character_list
- {
- public :
- scene_character *first;
- scene_character_list(char *&s);
- void inital_states(char *&s);
- scene_character *get(char *name);
- ~scene_character_list();
- } ;
-
- scene_character *scene_character_list::get(char *name)
- {
- scene_character *s=first;
- while (s)
- {
- if (!strcmp(s->n,name)) return s;
- s=s->next;
- }
- printf("Character %s not found!\n",name);
- exit(1);
- }
-
-
- scene_character_list::~scene_character_list()
- {
- scene_character *p;
- while (first)
- {
- p=first;
- first=first->next;
- delete p;
- }
- }
-
- scene_character_list::scene_character_list(char *&s)
- {
- scene_character *cur;
- expect(token_type(s),sLEFT_PAREN,s);
- next_token(s);
-
- cur=first=new scene_character(s);
-
- while (token_type(s)!=sRIGHT_PAREN)
- {
- cur->next=new scene_character(s);
- cur=cur->next;
- }
- next_token(s);
- }
-
-
- void scene_character_list::inital_states(char *&s)
- {
- char ch[50],seq[50];
-
- do
- {
- expect(get_token(s,ch),sLEFT_PAREN,s);
- expect(get_token(s,ch),sWORD,s);
- expect(get_token(s,seq),sWORD,s);
- scene_character *c=first;
- while (c && strcmp(c->n,ch)) c=c->next;
- if (!c)
- {
- printf("No character named %s, at %s\n",ch,s);
- exit(0);
- } else c->set_seq(seq);
- expect(get_token(s,ch),sRIGHT_PAREN,s);
- } while (token_type(s)!=sRIGHT_PAREN);
- }
-
- class text_blocker
- {
- public :
- int x1,y1,x2,y2;
- text_blocker *next;
- text_blocker(int X1, int Y1, int X2, int Y2, text_blocker *Next)
- { x1=X1;
- y1=Y1;
- x2=X2;
- y2=Y2;
- next=Next;
- }
- } ;
-
-
- int text_draw(int y, int x1, int y1, int x2, int y2, char *buf,
- text_blocker *first, JCFont *font)
- {
- short cx1,cy1,cx2,cy2,word_size,word_len;
- screen->get_clip(cx1,cy1,cx2,cy2);
- screen->in_clip(x1,y1,x2,y2);
- int h=font->height()+2,w=font->width(),x=x1,dist;
- y+=y1;
- char *word_start;
-
- while (*buf)
- {
- do
- {
- if (*buf=='\\' && buf[1]=='n')
- {
- x=x1;
- y+=h*2;
- buf+=2;
- }
-
- // skip space
- if (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t')
- {
- x+=w;
- while (*buf==' ' || *buf=='\r' || *buf=='\n' || *buf=='\t') // skip space until next word
- buf++;
- }
-
- word_start=buf;
- for (word_len=0,word_start=buf,word_size=0;*buf && *buf!=' ' && *buf!='\r' && *buf!='\n' &&
- *buf!='\t' && (*buf!='\\' || buf[1]!='n');buf++,word_size+=w,word_len++);
-
- if (word_size<x2-x1) // make sure the word can fit on the screen
- {
- if (word_size+x>x2) // does word not fit on line?
- {
- y+=h; // go to next line
- x=x1;
- }
- }
-
-
- if (y+h<y1) // word on screen yet?
- x+=word_size;
-
- } while (y+h<y1); // if not on screen yet, fetch next word
-
- /* dist=100;
- for (n=first;n;n=n->next)
- {
- if (x<n->x1)
- minx=(n->x1-x);
- else if (x>n->x2)
- minx=(x-n->x2);
- else minx=0;
-
- if (y<n->y1)
- miny=(n->y1-y);
- else if (y>n->y2)
- miny=(y-n->y2);
- else miny=0;
-
- dist=min(dist,max(minx,miny));
- }
-
-
- if (dist<=8) dist=8;
- else if (dist>31) dist=31; */
-
- dist=31;
- if (y-y1<dist)
- if (y-y1<8) dist=8;
- else dist=y-y1;
- if (y2-y<dist)
- if (y2-y<8) dist=8;
- else dist=y2-y;
-
- if (y>y2) return 0;
-
- while (word_len--)
- {
- font->put_char(screen,x+1,y+1,*word_start,0);
- font->put_char(screen,x,y,*word_start,32-dist);
- word_start++;
- x+=w;
- }
-
- }
-
- screen->set_clip(cx1,cy1,cx2,cy2);
- return (y<=y1);
- }
-
-
- struct scene_data_struct // define a name for the structure so that we can inspect in gdb
- {
- int x1,y1,x2,y2,
- pan_vx,pan_yv,pan_steps,
- frame_speed,scroll_speed,pan_speed;
- } scene_data;
-
-
-
-
-
- void play_scene(char *script, char *filename, JCFont *font)
- {
- char *s=script;
- char token[90];
- text_blocker *text_blockers=NULL;
-
- char *strng=(char *)jmalloc(MAX_SCROLL_DATA,"tmp token space");
- strcpy(scene_filename,filename);
-
- int x1,y1,x2,y2,done,pan_xv=0,pan_yv=0,pan_steps=0,
- text_loaded=0,frame_speed=100,scroll_speed=50,pan_speed=60,abort=0,text_step=-2;
-
- short cx1,cy1,cx2,cy2;
-
- the_game->draw(1);
-
- screen->get_clip(cx1,cy1,cx2,cy2);
- screen->set_clip(the_game->viewx1,the_game->viewy1,
- the_game->viewx2,the_game->viewy2);
-
-
-
-
- expect(get_token(s,token),sLEFT_PAREN,s);
- scene_character_list cl(s);
- int y;
-
- do
- {
- expect(get_token(s,token),sLEFT_PAREN,s); // list of transitions start
- // ACTIONS
- time_marker *last_text_time=NULL;
- time_marker *last_pan_time=NULL;
- do
- {
- expect(get_token(s,token),sLEFT_PAREN,s);
- expect(get_token(s,token),sWORD,s);
-
- if (!strcmp(token,"pan"))
- {
- pan_xv=get_number(s);
- pan_yv=get_number(s);
- pan_steps=get_number(s);
- }
- else if (!strcmp(token,"states"))
- cl.inital_states(s);
- else if (!strcmp(token,"scroll_speed"))
- scroll_speed=get_number(s);
- else if (!strcmp(token,"pan_speed"))
- pan_speed=get_number(s);
- else if (!strcmp(token,"frame_speed"))
- frame_speed=get_number(s);
- else if (!strcmp(token,"text_region"))
- {
- x1=the_game->viewx1+get_number(s);
- y1=the_game->viewy1+get_number(s);
- x2=the_game->viewx1+get_number(s);
- y2=the_game->viewy1+get_number(s);
- y=y2-y1;
- } else if (!strcmp(token,"text_block"))
- {
- int sx1=get_number(s)+the_game->viewx1;
- int sy1=get_number(s)+the_game->viewy1;
- int sx2=get_number(s)+the_game->viewx1;
- int sy2=get_number(s)+the_game->viewy1;
- text_blockers=new text_blocker(sx1,sy1,sx2,sy2,text_blockers);
- } else if (!strcmp(token,"block"))
- {
- int sx1,sy1,sx2,sy2;
- expect(get_token(s,token),sWORD,s);
- cl.get(token)->area(sx1,sy1,sx2,sy2);
- text_blockers=new text_blocker(sx1,sy1,sx2,sy2,text_blockers);
- }
- else if (!strcmp(token,"scroll"))
- {
- expect(get_token(s,strng),sSTRING,s);
- text_loaded=1;
- y=y2-y1;
- } else if (!strcmp(token,"wait"))
- {
- expect(get_token(s,token),sWORD,s);
- printf("waiting for %s\n",token);
- done=0;
-
-
-
-
- int old_dev=dev;
- dev=dev&(0xffff-DRAW_PEOPLE_LAYER);
-
-
- do
- {
- the_game->draw_map();
-
- time_marker cur_time;
- if (pan_steps)
- {
- if (last_pan_time)
- {
- if ((int)(cur_time.diff_time(last_pan_time)*1000)>pan_speed)
- {
- the_game->pan(pan_xv,pan_yv);
- pan_steps--;
- delete last_pan_time;
- if (pan_steps)
- last_pan_time=new time_marker;
- else last_pan_time=NULL;
- }
- } else last_pan_time=new time_marker;
- }
-
- scene_character *first=cl.first;
- while (first)
- {
- first->draw();
-
- if (!first->last_frame)
- first->last_frame=new time_marker;
- else
- {
- int time=first->current_frame->time,advance=0;
- if (time>=0)
- {
- if ((int)(cur_time.diff_time(first->last_frame)*1000)>time)
- advance=1;
- }
- else
- {
- if ((int)(cur_time.diff_time(first->last_frame)*1000)>frame_speed)
- advance=1;
- }
-
- if (advance)
- {
- if (!strcmp(token,first->n)) // is this the character we are waiting on?
- {
- if (first->next_frame())
- done=1;
- } else first->next_frame();
- }
- }
- first=first->next;
- }
- if (text_loaded)
- {
- text_loaded=(!text_draw(y,x1,y1,x2,y2,strng,text_blockers,font));
- if (last_text_time)
- {
- if ((int)(cur_time.diff_time(last_text_time)*1000)>scroll_speed)
- {
- y+=text_step;
- delete last_text_time;
- if (text_loaded)
- last_text_time=new time_marker;
- else
- last_text_time=NULL;
- }
- } else last_text_time=new time_marker;
- }
-
-
-
- if (!strcmp(token,"pan"))
- if (pan_steps<=0) done=1;
-
- if (!strcmp(token,"text"))
- if (!text_loaded) done=1;
-
- eh->flush_screen();
- while (eh->event_waiting())
- {
- event ev;
- eh->get_event(ev);
- if (ev.type==EV_KEY)
- {
- switch (ev.key)
- {
- case JK_UP :
- case JK_LEFT :
- if (scroll_speed>=20)
- scroll_speed-=20;
- else text_step--;
- break;
- case JK_RIGHT :
- case JK_DOWN :
- if (text_step<-2)
- text_step++;
- else if (scroll_speed<200) scroll_speed+=20;
- break;
- case JK_ESC : abort=done=1; break;
- case JK_ENTER : done=1; break;
- }
- }
- }
-
-
- } while (!done);
- dev=old_dev;
- }
-
- expect(get_token(s,token),sRIGHT_PAREN,s);
-
- } while (!abort && token_type(s)!=sRIGHT_PAREN);
-
-
- if (!abort)
- next_token(s);
-
- // free up memory allocated
- while (text_blockers)
- {
- text_blocker *n=text_blockers->next;
- delete text_blockers;
- text_blockers=n;
- }
- if (last_text_time)
- delete last_text_time;
- if (last_pan_time)
- delete last_pan_time;
-
- } while (!abort && token_type(s)!=sRIGHT_PAREN);
- if (!abort)
- next_token(s);
-
- jfree(strng);
- screen->set_clip(cx1,cy1,cx2,cy2);
-
- the_game->draw(0);
- }
-
-
-
-